// MODULE
const { notes, pengguna, bookmark } = require('../db/schema')
const bcrypt = require('bcrypt');
//const { registerPartial } = require('handlebars');
const fs = require('fs');
const { send } = require('process');
const { doesNotMatch } = require('assert');
const url = require('url');




const routes = app => {

	//PUBLIC
	// GET
	app.get('/', async(request, reply) => {
		try{
			const sessionData = request.session.get('data');
			if(sessionData === undefined){
				return reply.view('./html/index.hbs', {
					title: 'Login'
				})
			}
			origin = request.routerPath
			console.log("ORIGIN =>", origin)

			const page = request.query.page || 1;

			if(sessionData.role === 'superuser') {
				const data = await bookmark.paginate({}, {
					'page': page,
					'limit': 25,
					sort: {
						createdAt: -1
					},
					'lean': true
				})
				return reply.view('./html/dashboard.hbs', {
					title: 'Bookmarknya Kus',
					bookmark: data,
					user: sessionData,
					origin: origin 
				})
			}
			
			// if not superuser
			const data = await bookmark.paginate({
				tags: {
					$ne: 'nsfw'
				}
			}, {
				'page': page,
				'limit': 25,
				sort: {
					createdAt: -1
				},
				'lean': true
			})
			
			return reply.view('./html/t.hbs', {
				title: 'Bookmarknya Kus',
				bookmark: data,
				user: sessionData,
				origin: origin
			})
		}catch(err){
			reply.send(err)
		}
	})

	// Profil
	app.get('/profil', async (request, reply) => {
		try{
			const sessionData = request.session.get('data');
			if(sessionData === undefined){
				return reply.view('./html/index.hbs', {
					title: 'Login'
				})
			}

			const user = sessionData.user
			const userProfile = await pengguna.findOne({username: user}).lean();
			const count = await bookmark.aggregate([{ $count: "url"}])
			
			const getTags = await bookmark.find();
			const aggrTags = await bookmark.aggregate([{
				$project: {
					_id: 0,
					tagslist: {
						$concatArrays: getTags.map(obj => obj.tags)
					}
				}
			}]);

			const arr = aggrTags[0].tagslist.sort().filter((urut, index) => {
				return aggrTags[0].tagslist.sort().indexOf(urut) === index
			})

			const simpan = await bookmark.find({}, {
				_id: 0,
				__v: 0,
				createdAt: 0,
				updatedAt: 0
			});
			const json = simpan.toString();

			fs.writeFile(`./assets/dl/ekspor-${sessionData.user}.json`, json, (err) => {
				if (err) throw err;
			});

			return reply.view('./html/profile.hbs', {
				title: 'Bookmarkus : profile',
				data: userProfile,
				user: sessionData,
				sum: count,
				ctags: arr.length
			})
		}catch(err){
			reply.send(err)
		}
	})

	// Notes
	app.get('/notes', async (request, reply) => {
		try{
			const url = request.url;
			const sessionData = request.session.get('data');
			if (sessionData === undefined) {
				return reply.view('./html/index.hbs', {
					title: 'Login'
				})
			}
			return reply.view('./html/notes.hbs', {
				title: 'Notekus',
				user: sessionData,
				url: url
			})
		}catch(err){
			return reply.send(err)
		}
	})

	app.get('/note', async (request, reply) => {
		try{
			const note = await notes.find({}).lean();
			return reply.send(note);
		}catch(err){
			reply.send(err)
		}
	})

	app.get('/login', async (request, reply) => {
		try{
			return reply.status('302').redirect('/')
		}catch(err){
			reply.send(err)
		}
	})

	// Hapus data
	app.get('/hapus/:id', async (request, reply) => {
		try{
			const sessionData = request.session.get('data');
			if(sessionData === undefined) { return 'Mau apa?'}
			let _id = request.params.id;

			const hapusData = await bookmark.findByIdAndRemove(_id);
			request.flash('Info', `Bookmark dengan ID : ${_id} berhasil dihapus`)
			const masalah = reply.flash('info')

			return reply.status(302).redirect('/', {
				error: masalah
			})
		}catch(err){
			reply.send(err)
		}
	})

	
	// Input page
	app.get('/input', async (request, reply) => {
		try{
			const sessionData = request.session.get('data');
			if (sessionData === undefined) {
				return reply.view('./html/index.hbs', {
					title: 'Login'
				})
			}
			return reply.view('./html/input.hbs', {
				title: 'Input Bookmarks',
				user: sessionData
			})
		}catch(err){
			reply.send(err)
		}
	})

	app.get('/baca', async(request, reply) => {
		try {
			const sessionData = request.session.get('data')
			if(sessionData === undefined){
				return  {
					error: 'matamu!'
				}
			}
		
			const data = await bookmark.paginate({ 'nanti': 'on' }, { 'lean': true }) 
			origin = request.routerPath
			o = origin.split('/')
			console.log('ORIGIN =>', o[1])
			return reply.view('./html/dashboard.hbs', {
				title: 'yg belum terbaca',
				bookmark: data,
				user: sessionData,
				origin: o[1]
			})
		}catch(err){
			return (err)	
		}
	})


	// Masih bermasalah
	// Menenentukan next page
	// 
	app.get('/baca/:id', async (request, reply) => {
		try{
			const sessionData = request.session.get('data');
			if(sessionData === undefined) {
				return "matamu!"
			}

			const _id = request.params.id;
  			const nanti = "off"

			refr = request.header
			console.log(refr)
		
			//const q = url.parse(request.url, true);
			//const pathawal = q.pathname.split('/')[1];
			//const arr = ['/',pathawal]
			//const originalUrl = arr.join('')
			//console.log(originalUrl)
			
			const sudahBaca = await bookmark.findByIdAndUpdate(_id, {
				nanti: nanti
			}, {new: true})
			return reply.status('302').redirect('/') 
		}catch(err){
			reply.send(err)
		}
	})

	

	// Input - edit
	app.get('/edit/:id', async (request, reply) => {
		try{
			const sessionData = request.session.get('data');
			if (sessionData === undefined) {
				return reply.view('./html/index.hbs', {
					title: 'Login'
				})
			}
			let id = request.params.id;
			const data = await bookmark.findOne({_id: id}).lean()
			return reply.view('./html/input.hbs', {
				title: 'Edit Bookmarks',
				bookmark: data,
				id: id,
				user: sessionData
			})
		}catch(err){
			reply.send(err)
		}
	})


	app.get('/tags/:tag', async (request, reply) => {
		try{
			const sessionData = request.session.get('data');
			if (sessionData === undefined) {
				return reply.view('./html/index.hbs', {
					title: 'Login'
				})
			}
			const page = request.query.page || 1;
			const tag   = request.params.tag;
			
			if(sessionData.role == 'superuser'){
				const data = await bookmark.paginate({
					tags: tag
				}, {
					"page": page,
					"limit": 25,
					"sort": {
						createdAt: -1
					},
					'lean': true
				})
	
				return reply.view('./html/dashboard.hbs', {
					title: 'Bookmarknya Kus',
					bookmark: data,
					key: tag,
					user: sessionData
				})
			}		
			
			if(tag == 'nsfw') {
				return reply.status(302).redirect('/')
			}
			const data = await bookmark.paginate({
				 tags: tag
			}, {
				"page": page,
				"limit": 25,
				"sort": {
					createdAt: -1
				},
				'lean': true
			})

			return reply.view('./html/dashboard.hbs', {
					title: 'Bookmarknya Kus',
					bookmark: data,
					user: sessionData,
					key: tag
			})
			

		}catch(err){
			reply.send(err)
		}
	})

	app.get('/tagslist', async (request, reply) => {
		try{
			const getTags = await bookmark.find();
			const aggrTags = await bookmark.aggregate([{
				$project: {
					_id: 0,
					tagslist: {
						$concatArrays: getTags.map(obj => obj.tags)
					}
				}
			}]);
			
			const arr = aggrTags[0].tagslist.sort().filter((urut, index) => {
				return aggrTags[0].tagslist.sort().indexOf(urut) === index
			})
			const t = arr => {
				const map = arr.reduce((a, v) => {
					let c = v.charAt(0).toUpperCase();
					a[c] = [].concat((a[c] || []), v);
					return a;
				}, {});
				const hasil = Object.keys(map).map(el => ({
					abjad: el,
					tags: map[el]
				}));
				return hasil;
			};
			return reply.send(t(arr))

		}catch(err){
			reply.send(err)
		}
	})

	app.get('/cari', async (request, reply) => {
		try{
			const sessionData = request.session.get('data')
			if (sessionData === undefined) {
				return reply.view('./html/index.hbs', {
					title: 'Login'
				})
			}

			const keyword = request.query.q;
			if(keyword == 'ernie'){
				return reply.status(301).redirect('/e')
			}
			const url = request.url;

			const page = request.query.page || 1;
			const data = await bookmark.paginate({
				$text: {
					$search: keyword
				}}, {
					"page": page,
					"limit": 25,
					sort: {
						createdAt: -1
					},
					lean: "true"
			});
			return reply.view('./html/dashboard.hbs', {
				title: 'Bookmarknya Kus',
				bookmark: data,
				user: sessionData,
				q: keyword,
				u: url
			})
		}catch(err){
			reply.send(err)
		}
	})

	app.get('/e', async(request, reply) => {
		try{
			const sessionData = request.session.get('data')
			if(sessionData === undefined) {
				return reply.send(401).send('Masih dibawah umur!. Minggat!!')
			}
			return reply.header('content-type', 'text/html; charset=utf-8').send(`
				<img src="https://i.ibb.co/d4c1ND8/ernie.jpg" alt="ernie" border="0">
			`)
		}catch(err){
			console.log(err)
		}
	})

	app.get('/logout', async(request, reply) => {
		try{
			request.session.delete()
			await reply.status('302').redirect('/')
		}catch(err){
			reply.send(err)
		}
	})

	// Testing
	app.get('/t', async(request, reply) => {
		try{
			r = request.query.ref
			if(r == 'baca') {
				return { 'ref': r }
			}
			return { 'ref': 'salah' }	
		}catch(err){
			reply.send(err)
		}
	})

	app.get('/ekspor', async (request, reply) => {
		try{
			const sessionData = request.session.get('data');
			if(sessionData === undefined){ return 'Not Allowed'}

			reply.type('application/json').send(fs.readFileSync(`./assets/dl/ekspor-${sessionData.user}.json`))
 		}catch(err){
			reply.send(err)
		}
	})

	// API
 	// POST
	// Create User
	app.post('/buat-user', async(request, reply) => {
		try{
			const sessionData = request.session.get('data')
			if(sessionData === undefined) {
				return reply.send('Tidak diijinkan')
			}
			const username	= request.body.username;
			const pass = request.body.password;
			const role = request.body.role;

			const h = 12;
			const hashPass = await bcrypt.hash(pass,h)

			const buatUser = new pengguna({ 
				username: username,
				password: hashPass,
				role: role
			}) 
			return buatUser.save();
		}catch(err){
			reply.send(err)
		}
	})

	// rubah password
	app.post('/edit-user', async(request, reply) => {
		try{
			const sessionData = request.session.get('data')
			if (sessionData === undefined) {
				return reply.send('Tidak diijinkan')
			}
			const id = request.body.id;
			const lama = request.body.passlama;
			const baru = request.body.passbaru;

			const cekId = await pengguna.findOne({_id: id})
			if(cekId) {
								
				const cekPassLama = await bcrypt.compare(lama, cekId.password)
				if(cekPassLama === true) {
					const cryptPassBaru = await bcrypt.hash(baru, 12)
					const updateData = await pengguna.findByIdAndUpdate(id, {
						'password': cryptPassBaru
					}, {
						new: true
					})
					updateData.save();
					request.session.delete()
					return reply.view('./html/gp.hbs', { title: 'Sukses!'})
				}
			}
			reply.send('User tidak ditemukan')
		}catch(err){
			reply.send(err)
		}
	})

	// login
	app.post('/login', async(request, reply) => {
		try{
			let username = request.body.username;
			let password = request.body.password;
		    
			request.flash('warning', 'Username atau Password salah!')
			const masalah = reply.flash('warning')

     		const cekPengguna = await pengguna.findOne({username: username})
			if(cekPengguna){
				const decPass = await bcrypt.compare(password, cekPengguna.password)
				if(cekPengguna.username  === username && decPass === true){
					request.session.set('data', {
						'user': cekPengguna.username,
						'role': cekPengguna.role
				})
				return reply.status('302').redirect('/')
			}}

			return reply.view('./html/index.hbs', {
				title: 'Login',
				warning: masalah
			})
		}catch(err){
			reply.send(err)
		}
	})

	// Input Data
	app.post('/input', async (request, reply) => {
		try{
			const sessionData = request.session.get('data')
			if (sessionData === undefined) {
				return reply.send('Tidak diijinkan')
			}
			let url = request.body.url;
			let judul = request.body.judul;
			let uraian = request.body.uraian;
			let rtags = request.body.tags || 'bookmark'
			let tags = rtags.split(' ')
			let nanti = request.body.nanti;

			const inputData = new bookmark({
				'url': url,
				'judul': judul,
				'uraian': uraian,
				'tags': tags,
				'nanti': nanti
			})
			inputData.save()
			return reply.status('302').redirect('/')
		}catch(err){
			reply.send(err)
		}
	})

	// Edit data
	app.post('/edit', async (request, reply) => {
		try{
			const sessionData = request.session.get('data')
			if (sessionData === undefined) {
				return reply.send('Tidak diijinkan')
			}
			let id = request.body.id;
			let url = request.body.url;
			let judul = request.body.judul;
			let uraian = request.body.uraian;
			let rtags = request.body.tags;
			let tags = rtags.split(',')
			let nanti = request.body.nanti;

			const editData = await bookmark.findByIdAndUpdate(id, {
				'url ': url,
				'judul': judul,
				'uraian': uraian,
				'tags': tags,
				'nanti': nanti
			}, {new: true})
			return reply.status('302').redirect('/')
		}catch(err){
			reply.send(err)
		}
	})

	// Import Data
	app.post('/impor', async (request, reply) => {
		try{
			const imporData = bookmark.insertMany(request.body)			
			return imporData;
	
		}catch(err){
			reply.send(err)
		}
	})

	app.post('/notes', async (request, reply) => {
		try{
			let judul = request.body.judul;
			let isi = request.body.isi;

			let inputNotes = new notes({
				'judul' : judul,
				'isi' : isi
			})
			inputNotes.save();
			return inputNotes;
		}catch(err){
			return reply.send(err)
		}
	})

	app.get('/poes', async (request, reply) => {
		try{
			const sessionData = request.session.get('data')
			
			let data = sessionData.user;
			console.log(data)
			let insert = await bookmark.insertMany({user: data})
			return insert;
		}catch(err){
			console.log(err)
		}
	});

}; // end of the road

module.exports = { routes };
